详谈为什么互联网公司严禁使用自增主键

三个问题

  • 大表为什么不能用自增主键?
  • UUID 是好的替代方案吗?
  • SnowFlake 雪花算法是什么?

自增主键

自增主键是数据库根据插入数据库行,按顺序自动赋予的一个连续的值,如下:(id int auto_increment)
在这里插入图片描述
这种形式的主键本身是没有什么问题的,在学校做个毕业设计或者在创业型公司使用是没什么问题的。但是你是在大型公司(淘宝、京东等电商项目)分布式情况下使用是有严重问题的。接下来我们进行分析

案例:如下有个商品表,里面有三亿数据,数据库表有三个分片

在这里插入图片描述
假设我们按照自增主键方式进行分片存储 0-1 在分片 1、1-2 在分片 2、2-3 在分片 3,按照设计来看的话没什么问题,但实际有非常严重的问题,接下来进行讲解

a . 资源浪费
还是如上图,分表在三个数据库分别有三个表分片,你怎么知道那个数据库中的分片,可以容纳 1 亿数据呢,这是不是猜的呢

也行某些一行记录数据量比较小,在某个分片上可以存储 1.5 亿条数据呢,那还能再扩展呢?答案是肯定不能的,应为设计的时候依据按照范围分片的方式已经设计好的。且自增主键必须连续只能采用”范围分片”形式

b. 尾部热点
自增主键分片又会带来一个附加的效应技术尾部热点,这是由范围分片自身的特定决定的。

比如说,现在我们的商品数据已经堆积到 2.5 亿,新的数据在插入的时候,所有的数据都被插入到了分片3中,之前的分片 1 2 都不会有写入操作,所以表分片3中库的压力是非常大的。

当然,对于这样的情况也是有解决方案的。即 HASH 法,这种情况的分片相比范围法效率上高1.5倍之多。


UUID 或 GUID

面对自增主键产生的问题,有些公司会使用 UUID 或 GUID 的主键。使用UUID可以替代自增主键吗?答案是,不可以!为什么呢,接下来我们进行讲解

首先看下面的 UUID ,他是 128 位长的且是无序的

0b7a900d-7e0c-4d14-b081-a20bdf1f1264
d09bc3ab-9670-4355-9614-ab2bc5ca6fd9
251ae4de-e3af-43cf-8287-77a944d2703f
ad397986-4bd9-4986-9f38-eb81042c7492

为什么这种无序的字符串不能作为我们的主键呢,这样从 MySQL的 InnoDB(B+数)引擎数据库底层机制说起。

使用UUID是无序的,作为主键会涉及大量索引重排


Snowflake

面对自增主键与UUID产生的问题,有没有解决方案呢?答案是有的,即 Snowflake(雪花算法)。

雪花算法(Snowflake)是 Twitter 公司分布式项目采用的 ID 生成算法。他呢主要是根据时间顺序,结合机器ID与序列,生成一个定长的数字。

这个数字就可以作为数据库的主键,他既可以保证是连续的也可以保证在分布式系统中是唯一的。

Snowflake 每毫秒可以生成 416 万个 ID,这对于我们在分布式系统中使用的场景已经足够了。

注意
实现雪花算法时要注意时间回拨带来的影响。就是在实际使用过程中,程序所处的服务器,时间往前或者往后调个几毫秒,这种情况下会产生重复的 ID。这种情况在实际几乎是不会遇到的。

  • 17
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜鸟厚非

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值